package ws

import (
	"fmt"
	"net/http"
	"strconv"

	"github.com/gorilla/websocket"
	"xgame.go_server/comm/log"
)

var nSessionUId int32 = 0

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

//
// StartServer 启动 Websocket 服务器
//
// bindHost = 绑定主机地址,
// bindPort = 绑定端口号,
// rootPath = 根目录, 例如: /ws 或者 /websocket
func StartServer(bindHost string, bindPort int, rootPath string) {
	if len(bindHost) <= 0 ||
		bindPort < 1000 {
		log.Error("主机地址或端口号不正确")
		return
	}

	go func() {
		http.HandleFunc(rootPath, websocketHandshake)
		_ = http.ListenAndServe(
			bindHost+":"+strconv.Itoa(bindPort),
			nil,
		)
	}()
}

//
// Websocket 握手,
// 其实就是处理 Websocket Upgrade 协议
func websocketHandshake(w http.ResponseWriter, r *http.Request) {
	// 升级为 WebSocket
	clientConn, err := upgrader.Upgrade(w, r, nil)

	if nil != err {
		log.Error("UpgradeError: %+v", err)
		return
	}

	defer func(c *websocket.Conn) {
		err := c.Close()
		if nil != err {
			log.Error("%+v", err)
		}
	}(clientConn)

	nSessionUId++

	log.Info(
		"有客户端连入, sessionUId = %d",
		nSessionUId,
	)

	newCtx := &cmdCtx{
		sessionUId:   fmt.Sprintf("%d", nSessionUId),
		clientConn:   clientConn,
		clientIpAddr: clientConn.RemoteAddr().String(),
	}

	TheCmdCtxGroup().Add(newCtx)
	defer TheCmdCtxGroup().DeleteBySessionUId(newCtx.sessionUId)

	// 开始循环发送消息
	newCtx.startLoopSendMsg()
	// 循环读取消息
	newCtx.loopReadMsg()
}
